/*
 * $Id: ArticleJsonServlet.java 49 2012-02-21 14:42:26Z rook.alex@gmail.com $
 */
package ua.org.energy.vkek.site.web;

import com.google.appengine.api.datastore.Text;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import ua.org.energy.vkek.site.model.Article;
import ua.org.energy.vkek.site.server.ArticleUtils;
import ua.org.energy.vkek.site.server.DataIOException;
import ua.org.energy.vkek.site.server.EMF;

public class ArticleJsonServlet extends BaseJsonServlet {

    @Override
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/javascript;charset=UTF-8");

        Article article;

        PrintWriter out = response.getWriter();

        String action = request.getParameter("action");
        if (checkParamValue(action)) {
            if (action.equalsIgnoreCase("ins")) {
                article = attachToTag(request);
                printArticleOk("insert", article, out);
            } else if (action.equalsIgnoreCase("upd")) {
                article = update(request);
                printArticleOk("update", article, out);
            } else if (action.equalsIgnoreCase("del")) {
                delete(request);
                printArticleOk("delete", null, out);
            } else if (action.equalsIgnoreCase("get")) {
                printArticleData(request, out);
            } else {
                throw new ServletException("an unknown action");
            }
        } else {
            String tag = request.getParameter("seltag");
            if (checkParamValue(tag)) {
                printArticleListForTag(tag, out);
            } else {
                printArticleList(out);
            }
        }
        out.close();
    }

    /*
     * UID on Articles
     */
    private Article attachToTag(HttpServletRequest request) throws DataIOException {
        String tag = request.getParameter("seltag");
        String articleTitle = request.getParameter("atitle");
        String acontent = checkParamValue(request.getParameter("content")) ? request.getParameter("content") : "";
        acontent = acontent.trim(); //TODO: создать задачу/очередь для проверки и обработки загруженных пользователем статей

        if (checkParamValue(tag) && checkParamValue(articleTitle)) {
            Article result = new Article();
            result.setArticleTitle(articleTitle);
            result.setContent(new Text(acontent));
            ArticleUtils utils = new ArticleUtils(EMF.getEM());
            result = utils.attachToTag(tag, result);
            EMF.safeCommit(EMF.getEM());
            return result;
        } else {
            throw new DataIOException("not enough parameters while creating article, in operation insert "
                    + request.getQueryString());
        }
    }

    private Article update(HttpServletRequest request) throws DataIOException {
        String articleTitle = request.getParameter("atitle");
        String articleKey = request.getParameter("akey"); //сохранять в скрытом поле
        String content = request.getParameter("content");

        if ((checkParamValue(articleTitle))
                && (checkParamValue(articleKey))) {
            ArticleUtils utils = new ArticleUtils(EMF.getEM());
            Article result = utils.updateWise(stringToKey(articleKey), articleTitle, content);
            EMF.safeCommit(EMF.getEM());
            return result;
        } else {
            throw new DataIOException("not enough parameters while update article title, in operation update");
        }
    }

    private void delete(HttpServletRequest request) throws DataIOException {
        String articleKey = request.getParameter("akey"); //сохранять в скрытом поле
        if (checkParamValue(articleKey)) {
            ArticleUtils utils = new ArticleUtils(EMF.getEM());
            utils.delete(stringToKey(articleKey));
            EMF.safeCommit(EMF.getEM());
        } else {
            throw new DataIOException("not enough parameters while delete article");
        }
    }

    /*
     * lists
     */
    private void printArticleListForTag(String tag, PrintWriter out) throws DataIOException {
        ArticleUtils utils = new ArticleUtils(EMF.getEM());
        List<EntityUIDJson> list = createEntityJsonList("get/meta", utils.listForTag(tag));
        printGson(list, out);
    }

    private void printArticleList(PrintWriter out) {
        ArticleUtils utils = new ArticleUtils(EMF.getEM());
        List<EntityUIDJson> list = createEntityJsonList("get/meta", utils.listAll());
        printGson(list, out);
    }

    private List<EntityUIDJson> createEntityJsonList(String operation, List<Article> list) {
        if (list != null) {
            List<EntityUIDJson> result = new ArrayList<EntityUIDJson>(list.size());
            for (Article a : list) {
                EntityUIDJson<Article> uidjson = new EntityUIDJson<Article>(operation, a);
                result.add(uidjson);
            }
            return result;
        } else {
            return null;
        }
    }

    /**
     * выводит в out JSON объект - результат uid-операции над Article
     */
    private void printArticleOk(String operation, Article article, PrintWriter out) {
        printArticleOk(operation, article, out, true);//используется укороченный com.google.appengine.api.datastore.Text
    }

    private void printArticleOk(String operation, Article article, PrintWriter out, boolean makeShortText) {
        EntityUIDJson<Article> uidjson = new EntityUIDJson<Article>(operation, article);
        printOk(uidjson, out, makeShortText);
    }

    private void printArticleData(HttpServletRequest request, PrintWriter out) throws DataIOException {
        String articleKey = request.getParameter("akey"); //сохранять в скрытом поле
        if (checkParamValue(articleKey)) {
            ArticleUtils utils = new ArticleUtils(EMF.getEM());
            Article target = utils.findArticle(stringToKey(articleKey));
            if (target == null) {
                throw new DataIOException("could not find article for key=" + articleKey);
            }
            if (request.getParameter("meta") != null) {
                printArticleOk("get/meta", target, out);
            } else if (request.getParameter("content") != null) {
                printArticleOk("get/content", target, out, false); //вывод полного com.google.appengine.api.datastore.Text
            } else {
                throw new DataIOException("not enough parameters while getting article");
            }
        } else {
            throw new DataIOException("not enough parameters while getting article, in operation get "
                    + request.getQueryString());
        }
    }
}
